home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
wwindow2.arc
/
WINDOW.C
< prev
next >
Wrap
Text File
|
1986-08-11
|
10KB
|
456 lines
/*-------------------------------------*/
/*- */
/*- Window */
/*- */
/*- */
/*-------------------------------------*/
static char copyright[] = "Copyright 1986 by Nourse, Gregg & Browne Inc.";
/* (201) 886-2642 Ft. Lee NJ 07024 */
#include "dos.h"
#define HI 0x08
#define WHITE '\x07'
#define CR '\x0d'
#define LF '\x0a'
#define BS '\x08'
#define FALSE '\0'
#define TRUE '\x01'
#define LEFT 75
#define RIGHT 77
#define ZIP '\0'
struct window_struct {
int top; /* top of window on display */
int left; /* left side of window */
int bottom; /* bottom of display */
int right; /* right most screen column */
int attr; /* character attribute for this window */
int row,col; /* window's virtual cursor position */
char *old; /* buffer to hold old screen contents */
char title_present; /* flag set if window has title */
};
static struct window_struct *ww[32];
static int wi=1;
static char dash[] = "═════════════════════════════════════════════════════";
static char *left_end = "╒";
static char *right_end = "╕";
static int row_stack[16];
static int col_stack[16];
static int cur_sp = 0;
static char *trim(ss)
char *ss;
{
int i;
i = strlen(ss) -1;
while (ss[i]==' ' && i>=0)
{
ss[i--] = '\0';
}
return(ss);
}
static wscroll(window,lines)
int window,lines;
{
union REGS rr;
struct window_struct *win;
win=ww[window];
rr.h.ah=6; /* func: scroll up */
rr.h.al=lines; /* number of line to scroll */
rr.h.ch=win->top; /* top left row, column */
rr.h.cl=win->left; /* top left row, column */
rr.h.dh=win->bottom; /* bottom row */
rr.h.dl=win->right; /* right column */
rr.h.bh=win->attr; /* blanking attr */
int10(&rr);
}
static char *save_area(top,left,bottom,right)
int top,left,bottom,right;
{
char *savea, *p;
int siz, row, col;
union REGS rr;
siz = (bottom - top + 1) * (right - left + 1) * 2 ;
p=savea=(char *)malloc(siz);
if (p==NULL) return(NULL);
for (row=top;row<=bottom;row++)
{
for (col=left;col<=right;col++)
{
rr.h.ah=2; /* func: set cursor position */
rr.h.dh=row; /* row # */
rr.h.dl=col; /* col # */
rr.h.bh=0; /* page zero */
int10(&rr);
rr.h.ah=8; /* func: read char */
rr.h.bh=0; /* page zero */
int10(&rr); /* read it */
*p++=rr.h.al; /* save the character */
*p++=rr.h.ah; /* save the attribute */
}
}
return(savea);
}
static restore_area(win)
int win;
{
int top, bottom, left, right;
char *p;
int row, col;
union REGS rr;
p=ww[win]->old;
if (p==NULL) return;
top=ww[win]->top;
bottom=ww[win]->bottom;
left=ww[win]->left;
right=ww[win]->right;
if (ww[win]->title_present) top-- ;
for (row=top;row<=bottom;row++)
{
for (col=left;col<=right;col++)
{
rr.h.ah=2; /* func: set cursor position */
rr.h.dh=row; /* row # */
rr.h.dl=col; /* col # */
rr.h.bh=0; /* page zero */
int10(&rr);
rr.h.ah=9; /* func: write char + attr */
rr.h.bh=0; /* page zero */
rr.x.cx=1; /* count */
rr.h.al=*p++; /* the character */
rr.h.bl=*p++; /* the attribute */
int10(&rr); /* write it */
}
}
free(ww[win]->old);
ww[win]->old=NULL;
}
static setpos(win)
int win;
{
union REGS rr;
if (ww[win]->col > ww[win]->right)
{
ww[win]->col=ww[win]->left;
ww[win]->row++;
}
if (ww[win]->row > ww[win]->bottom)
{
wscroll(win,1);
ww[win]->row=ww[win]->bottom;
}
rr.h.ah=2; /* func: set cursor position */
rr.h.dh=ww[win]->row; /* row */
rr.h.dl=ww[win]->col; /* column */
rr.h.bh=0; /* page zero */
int10(&rr);
}
static readpos(win)
int win;
{
union REGS rr;
rr.h.ah=3; /* func: read cursor position */
rr.h.bh=0; /* page zero */
int10(&rr); /* video int */
ww[win]->row=rr.h.dh;
ww[win]->col=rr.h.dl;
}
static save_cursor()
{
union REGS rr;
rr.h.ah=3; /* func: read cursor position */
rr.h.bh=0; /* page zero */
int10(&rr); /* video int */
cur_sp++; /* push */
row_stack[cur_sp]=rr.h.dh; /* row */
col_stack[cur_sp]=rr.h.dl; /* col */
}
static restore_cursor()
{
union REGS rr;
rr.h.dh=row_stack[cur_sp];
rr.h.dl=col_stack[cur_sp];
cur_sp--; /* pop */
rr.h.ah=2; /* func: set cursor position */
rr.h.bh=0; /* page zero */
int10(&rr);
}
static wputc(win,c)
int win;
char c;
{
union REGS rr;
switch (c)
{
case CR:
{
ww[win]->col=ww[win]->left;
break;
}
case LF:
{
if (ww[win]->row < ww[win]->bottom) ww[win]->row++;
else
{
wscroll(win,1);
ww[win]->row=ww[win]->bottom;
}
break;
}
case BS:
{
if (ww[win]->col > ww[win]->left) ww[win]->col--;
break;
}
default:
{
setpos(win);
rr.h.ah=9; /* func: write char and attr */
rr.h.bh=0; /* page zero */
rr.x.cx=1; /* one character */
rr.h.al=c; /* the byte */
rr.h.bl=ww[win]->attr; /* the char's attribute */
int10(&rr);
ww[win]->col++;
break;
}
}
}
static wblank(win,len)
int win, len;
{
int r,c, i;
r=ww[win]->row;
c=ww[win]->col;
for (i=0;i<len;i++) wputc(win,' ');
ww[win]->row=r;
ww[win]->col=c;
}
static char wgetc(win)
int win;
{
union REGS rr;
setpos(win);
rr.h.ah=8; /* func: read char */
rr.h.bh=0; /* page zero */
int10(&rr); /* video INT */
ww[win]->col++;
return(rr.h.al); /* the character */
}
void wprint(window_handle,text) /* print a string at window's cursor */
int window_handle; /* the handle from wopen() */
char *text; /* the string to print */
{
char *p;
save_cursor();
for (p=text;(*p!='\0');p++)
{
wputc(window_handle,*p);
}
restore_cursor();
}
int wopen(top,left,bottom,right,attr,title) /* returns 'window handle' */
int top, /* top row of window */
left, /* left side column */
bottom, /* bottom row of window */
right, /* right side column */
attr; /* the screen attribute for this window */
char *title; /* NULL or the title for the window (optional) */
{
int i, l, width, title_len, x;
struct window_struct *win = NULL;
for (i=1;i<wi;i++) { if (ww[i]==NULL) break; }
if (i==wi) wi++;
win=(struct window_struct *)malloc(sizeof(struct window_struct));
if (win==NULL) return(-1);
win->top=top;
win->left=left;
win->bottom=bottom;
win->right=right;
win->attr=attr;
win->col=left;
win->row=bottom;
win->title_present=FALSE;
ww[i]=win;
save_cursor();
win->old=save_area(top,left,bottom,right);
wscroll(i,0);
if (title!=NULL)
{
win->title_present=TRUE;
win->row=top;
win->attr=attr | WHITE ;
title_len=strlen(title) + 6;
width=(win->right - win->left)+1;
l=(width - title_len) / 2;
x=strlen(dash) - l;
wprint(i,left_end);
wprint(i,&dash[x]);
wprint(i,"╡ ");
win->attr=attr | WHITE | HI;
wprint(i,title);
win->attr=attr | WHITE ;
wprint(i," ╞");
l=(width - title_len) - l;
x=strlen(dash) - l;
wprint(i,&dash[x]);
wprint(i,right_end);
win->attr=attr;
win->col=left;
win->row=bottom;
win->top++;
}
restore_cursor();
return(i);
}
void wclose(window_handle) /* close the window, restore prior screen */
int window_handle; /* handle you got from wopen() */
{
save_cursor();
restore_area(window_handle);
free(ww[window_handle]);
ww[window_handle]=NULL;
restore_cursor();
}
void wlocate(window_handle,row,col) /* move cursor relative to origin */
int window_handle, /* the handle from wopen() */
row, /* the relative row (from 0) */
col; /* the relative column (from 0) */
{
ww[window_handle]->row=ww[window_handle]->top + row;
ww[window_handle]->col=ww[window_handle]->left + col;
}
void wsay(window_handle,row,col,text) /* move corsor + print text */
int window_handle, /* the handle from wopen() */
row, /* row to move cursor to */
col; /* columne to move cursor to */
char *text; /* text to print at that location */
{
wlocate(window_handle,row,col);
wprint(window_handle,text);
}
void winput(window_handle,row,col,field,len) /* input text from window */
int window_handle, /* handle from wopen() */
row, /* row to input from */
col, /* column to input from */
len; /* max length of input field */
char *field; /* default read from, and input put into here */
{
int first, last, i;
char c, s, *p;
union REGS rr;
save_cursor();
wlocate(window_handle,row,col);
wprint(window_handle,field);
wblank(window_handle,len-strlen(field));
wlocate(window_handle,row,col);
first=ww[window_handle]->col;
last=first+len-1;
for (c=ZIP;c!=CR;)
{
setpos(window_handle);
rr.h.ah=0;
int86(0x16,&rr,&rr);
c=rr.h.al;
s=rr.h.ah;
if (c >= ' ')
{
wputc(window_handle,c);
}
switch (s)
{
case RIGHT: ww[window_handle]->col++; break;
case LEFT: ww[window_handle]->col--; break;
default: break;
}
if (ww[window_handle]->col > last) ww[window_handle]->col=last;
if (ww[window_handle]->col < first) ww[window_handle]->col=first;
}
wlocate(window_handle,row,col);
for (p=field,i=0;i<len;p++,i++) *p=wgetc(window_handle);
*p=ZIP;
trim(field);
restore_cursor();
}
int wselect(window_handle,row,col,field,list) /* select from a list */
int window_handle, /* handle from wopen() */
row,col; /* window relative position */
char *field, /* copy of selection put here */
*list[]; /* vector of strings of selections */
{
int i, len, maxlen;
char c, s;
union REGS rr;
save_cursor();
for (i=0,maxlen=0;list[i]!=NULL;i++)
{
len=strlen(list[i]);
if (len>maxlen) maxlen=len;
}
for (i=0,c=0;c!=CR;)
{
wlocate(window_handle,row,col);
wblank(window_handle,maxlen);
wprint(window_handle,list[i]);
rr.h.ah=0;
int86(0x16,&rr,&rr);
c=rr.h.al;
s=rr.h.ah;
if (s==LEFT && i>0) i--;
if (c!=CR) i++;
if (list[i]==NULL) i=0;
}
strcpy(field,list[i]);
restore_cursor();
return(i);
}